package org.crud4j.wicket.markup.html.browse;

import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Button;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.crud4j.core.CrudBrowsePage;
import org.crud4j.core.CrudService;
import org.crud4j.wicket.CrudServiceInjectable;
import org.crud4j.wicket.markup.html.edit.EditModel;
import org.crud4j.wicket.markup.html.edit.EditPanel;

public class BrowsePanel extends Panel implements CrudServiceInjectable {

	private static final long serialVersionUID = 1L;

	private transient CrudService crudService;

	private class NewForm extends Form implements CrudServiceInjectable {

		private static final long serialVersionUID = 1L;

		private transient CrudService crudService;

		public NewForm(String id) {
			super(id);
		}

		@Override
		protected void onSubmit() {
			IModel model = BrowsePanel.this.getModel();
			BrowseModel browseModel = (BrowseModel) model.getObject();
			EditModel createModel = new EditModel(this.crudService
					.create(browseModel.getDefinition().getType()), model);
			// replace component with create
			BrowsePanel.this.replaceWith(new EditPanel(
					BrowsePanel.this.getId(), new Model(createModel)));
		}

		public void setCrudService(CrudService crudService) {
			this.crudService = crudService;
		}

	};

	private class PagingForm extends Form {

		public PagingForm(String id) {
			super(id);
			final BrowseModel browseModel = (BrowseModel) BrowsePanel.this
					.getModel().getObject();
			add(new Button("first") {
				public void onSubmit() {
					browseModel.setPage(0);
					reloadPage();
				}
			});

			add(new Button("previous") {
				public void onSubmit() {
					if (browseModel.getPage() > 0) {
						browseModel.setPage(browseModel.getPage() - 1);
						reloadPage();
					} else {
						// message
					}
				}
			});
			add(new Button("next") {
				public void onSubmit() {
					browseModel.setPage(browseModel.getPage() + 1);
					reloadPage();
				}
			});

			add(new Button("last") {
				public void onSubmit() {
					browseModel.setPage(browseModel.getPage() - 1);
					reloadPage();
				}
			});

			add(new Label("currentPage", browseModel.getPage().toString()));

		}

		private void reloadPage() {
			BrowseModel browseModel = (BrowseModel) BrowsePanel.this.getModel()
					.getObject();

			CrudBrowsePage page = crudService.filteredBrowse(browseModel
					.getDefinition().getType(), browseModel.getPageSize(),
					browseModel.getPage(), browseModel.getFilters());

			// add table panel
			BrowsePanel.this.replace(new BrowseRowsList("rows",
					this.getModel(), page.getBeans()));

			// replace page number
			replace(new Label("currentPage", browseModel.getPage().toString()));

		}

	};

	public BrowsePanel(String id, IModel model) {
		super(id, model);

		BrowseModel browseModel = (BrowseModel) model.getObject();

		// feedback
		FeedbackPanel feedback = new FeedbackPanel("feedback");
		add(feedback);

		// add filter panel
		add(new NewForm("newForm"));

		// add filter panel
		add(new BrowseFilterPanel("filter", model));

		CrudBrowsePage page = crudService.filteredBrowse(browseModel
				.getDefinition().getType(), browseModel.getPageSize(),
				browseModel.getPage(), browseModel.getFilters());

		// add table panel
		add(new BrowseRowsList("rows", model, page.getBeans()));

		// add paging
		add(new PagingForm("pagingForm"));

	}

	public void setCrudService(CrudService crudService) {
		this.crudService = crudService;
	}

}
